package order;

import enums.GoodsStatus;
import enums.OrderItemType;
import enums.OrderStatus;
import goods.Goods;
import helper.CacheCallBack;
import helper.CacheHelper;
import models.constants.DeletedStatus;
import models.weixin.WebUser;
//import org.hibernate.impl.QueryImpl;
import org.hibernate.transform.Transformers;
import play.db.jpa.JPA;
import play.db.jpa.Model;
import product.merchant.ProductSpecMerchant;
import util.common.DateUtil;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 订单条目.
 */
@Entity
@Table(name = "order_items")
public class OrderItem extends Model {

    public static final String CACHE_BY_ORDER_ID = "CACHE_BY_ORDER_ID_";

    /**
     * 商品信息
     */
    @JoinColumn(name = "goods_id", nullable = true)
    @ManyToOne
    public Goods goods;

    /**
     * 订单信息
     */
    @JoinColumn(name = "order_id", nullable = true)
    @ManyToOne
    public Order order;

    /**
     * 购买数量
     */
    @Column(name = "buy_number")
    public Integer buyNumber;

    /**
     * 销售单价
     */
    @Column(name = "sale_price")
    public Double salePrice;

    /**
     * 总金额 = 销售单价*购买数量
     */
    @Column(name = "amount")
    public Double amount;

    /**
     * 成本价
     */
    @Column(name = "original_price")
    public Double originalPrice;

    /**
     * 合伙人价格
     */
    @Column(name = "partner_price")
    public Double partnerPrice;

    /**
     * 类型
     */
    @Column(name = "type")
    @Enumerated(EnumType.STRING)
    public OrderItemType type;


    /**
     * 状态
     */
    @Column(name = "status")
    @Enumerated(EnumType.ORDINAL)
    public GoodsStatus status;   //FIXME: OrderStatus or OrderItemStatus

    /**
     * 逻辑删除状态
     */
    @Column(name = "deleted")
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted;

    /**
     * 订单创建时间
     */
    @Column(name = "created_at")
    public Date createdAt;

    /**
     * 更新时间
     */
    @Column(name = "updated_at")
    public Date updatedAt;

    @Transient
    public String url;

    public String originalName = "";

    public String imagePath = "";


    public OrderItem() {
        super();
    }

    public OrderItem(Order order, ProductSpecMerchant product, Integer buyNumber) {
        this.goods = product.findGoods(order.webUser);
        this.order = order;
        this.buyNumber = buyNumber;
        //TODO 到时候 重新规划价格
//        this.facePrice = product.originalPrice;
//        this.originalPrice = product.originalPrice;
//        this.salePrice = product.salePrice;
        this.deleted = DeletedStatus.UN_DELETED;
        this.status = GoodsStatus.OPEN;
        this.createdAt = new Date();
        this.updatedAt = new Date();
    }

    public OrderItem(Order order, ProductSpecMerchant product, Integer buyNumber, OrderItemType type) {
        this.goods = product.findGoods(order.webUser);
        this.order = order;
        this.buyNumber = buyNumber;
        //TODO 到时候重新规划价格
//        this.facePrice = product.originalPrice;
//        this.originalPrice = product.originalPrice;
//        this.salePrice = product.salePrice;
        this.deleted = DeletedStatus.UN_DELETED;
        this.status = GoodsStatus.OPEN;
        this.type = type;
        this.createdAt = new Date();
        this.updatedAt = new Date();
    }


    public OrderItem(Order order, ProductSpecMerchant product, Double amount , Integer buyNumber, OrderItemType type) {
        this.goods = product.findGoods(order.webUser);
        this.order = order;
        this.buyNumber = buyNumber;
//        this.facePrice = product.originalPrice;
        this.amount = amount * buyNumber;
        this.originalPrice = product.merchantPrice;
        this.salePrice = amount;
        this.deleted = DeletedStatus.UN_DELETED;
        this.status = GoodsStatus.OPEN;
        this.type = type;
        this.createdAt = new Date();
        this.updatedAt = new Date();
    }



    /**
     * 更新对象.
     */
    public static OrderItem update(Long id, OrderItem newObject) {
        OrderItem item = OrderItem.findById(id);
        if (item == null) {
            return null;
        }
        item.save();
        return item;
    }

    public static Boolean delete(Long id) {

        OrderItem item = OrderItem.findById(id);
        if (item == null) {
            return Boolean.FALSE;
        }
        item.deleted = DeletedStatus.DELETED;
        item.save();
        return Boolean.TRUE;
    }


    public static List<OrderItem> getListByOrder(Order order) {
        return OrderItem.find("order.id = ? and deleted = ?", order.id, DeletedStatus.UN_DELETED).fetch();
    }

//    public static List<Map<String, Object>> findListByOrderWithSQL(Order order) {
//        StringBuilder sb = new StringBuilder(" select o.buyNumber as buyNumber,round(o.salePrice , 2) as salePrice,o.createdAt as createdAt,o.deleted as deleted,o.status as status,o.type as type,o.amount as amount,o.goods as goods from  OrderItem o where o.order.id = " + order.id + " and o.deleted = 0 order by createdAt desc ");
//        String hql = sb.toString();
//        Query query = JPA.em().createQuery(hql);
//        query.unwrap(QueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
//        List<Map<String, Object>> resultlist = query.getResultList();
//        return resultlist;
//    }

    public static OrderItem getByOrder(Order order) {
        return OrderItem.find("order.id = ? and deleted = ?", order.id, DeletedStatus.UN_DELETED).first();
    }

    /**
     * 判断 OrderItem 的购买数量
     *
     * @param id
     * @return
     */
    public static Long countByGoodsAndPayOrder(Long id, WebUser user) {
        return OrderItem.count("goods.serialId = ? and order.payedAt != null and order.webUser = ?", id , user);
    }

    /**
     * 判断 OrderItem 的今日购买次数
     *找出某人今天购买某个产品的次数
     * @param id
     * @return
     */
    public static  Long countByGoodsAndPayOredreTodayCount(long id ,WebUser user){
        return  OrderItem.count("goods.serialId=? and order.payedAt !=null and order.webUser=? and order.createdAt between ? and ?",id,user,DateUtil.getBeginOfDay(new Date()),DateUtil.getEndOfDay(new Date()));

    }

    public static Long getOrderItemCount(Order order) {
        return OrderItem.count("order.id = ? and deleted = ? ", order.id, DeletedStatus.UN_DELETED);
    }

    public static ProductSpecMerchant getProductSpecMerchantByOrderItem(OrderItem orderItem) {
        return ProductSpecMerchant.findById(orderItem.goods.serialId);
    }

    /**
     * 根据订单号 查询 OrderItems
     * 因为订单生成后, 不能进行对 orderItems 进行变动
     * 所以,此方法可以尽量避免查询数据库
     *
     * @param order
     * @return
     */
    public static List<OrderItem> findByOrder(final Order order) {
        return OrderItem.find("order = ? and deleted = ?", order, DeletedStatus.UN_DELETED).fetch();
//        return CacheHelper.getCache(CACHE_BY_ORDER_ID + order.id, new CacheCallBack<List<OrderItem>>() {
//            @Override
//            public List<OrderItem> loadData() {
//                return OrderItem.find("order = ? and deleted = ?", order, DeletedStatus.UN_DELETED).fetch();
//            }
//        });
    }
    public static ProductSpecMerchant getProductByOrderItem(OrderItem orderItem){
//        Long productId = Long.valueOf(orderItem.goods.serial.replace("PRODUCT_", "").trim());
        return ProductSpecMerchant.findById(orderItem.goods.serialId);
    }


    public static Long countByGoods(Long goodsId) {
        return OrderItem.count("deleted = ? and goods.id = ?" , DeletedStatus.UN_DELETED , goodsId);
    }

    public static List<OrderItem> findAllItemByGoodSerialId(long serialId){
        return find("deleted = ? and goods.serialId = ? order by id",DeletedStatus.UN_DELETED, serialId).fetch();
    }
}
